package com.biwin.module.security.starter.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import com.biwin.common.app.enums.BwSecurityExceptionEnum;
import com.biwin.common.app.exception.BwBasicException;
import com.biwin.core.main.event.SystemUserPasswordChangeEvent;
import com.biwin.module.org.api.service.ISystemUserService;
import com.biwin.module.org.api.vo.SystemUserVo;
import com.biwin.module.security.api.dto.UserPassDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * 用户相关
 *
 * @author biwin
 * @since 0.0.1
 */
@Api(tags = "框架核心控制器")
@RestController
@RequestMapping("/api/user")
public class CoreController {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private ISystemUserService systemUserService;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    /**
     * 更新指定 账户 的登录密码
     */
    @ApiOperation(value = "修改密码", httpMethod = "POST", notes = "用于在未登录时修改密码")
    @PostMapping("/updatePwd")
    public void updateAccountPassword(@RequestBody @Valid UserPassDto userPassDto) {
        SystemUserVo systemUserVo = systemUserService.findByAccount(userPassDto.getUsername());
        String encodeOldPassword = passwordEncoder.encode(userPassDto.getOldPassword());
        if (!StrUtil.equals(encodeOldPassword, systemUserVo.getPassword())) {
            throw new BwBasicException(BwSecurityExceptionEnum.USER_CREDENTIALS_ERROR);
        }
        String encodeNewPassword = passwordEncoder.encode(userPassDto.getNewPassword());
        if (passwordEncoder.matches(userPassDto.getOldPassword(), encodeNewPassword)) {
            throw new BwBasicException(BwSecurityExceptionEnum.NEW_AND_OLD_PASSWORD_CANNOT_EQ);
        }
        systemUserService.updatePassword(systemUserVo.getId(), encodeNewPassword);
        // 发送用户密码变更事件, 默认提出当前用户登录的所有用户.
        applicationContext.publishEvent(new SystemUserPasswordChangeEvent(systemUserVo.getAccount()));
    }
}
